package reflectdemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 姚东名
 * Date: 2024-10-10
 * Time: 16:28
 */
public class Test {
    //获得Class对象的三种方式
    public static void main1(String[] args) {
        try {
            //方法1：最常用的方法
            Class<?> c1 = Class.forName("reflectdemo.Student");
            //方法2:仅适用于在编译前就已经明确要操作的Class
            Class c2 = Student.class;
            //方法3：
            Student student = new Student();
            Class<?> c3 = student.getClass();
            //这几个类对象是否是同一个？
            System.out.println(c1.equals(c2));// true
            System.out.println(c1.equals(c3));// true
            System.out.println(c2.equals(c3));// true
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    public static void main(String[] args) {
        //reflectNewInstance();
        //reflectPrivateConstructor();
        //reflectPrivateField();
        reflectPrivateMethod();
    }

    // 反射私有方法
    private static void reflectPrivateMethod() {
        try {
            Class<?> c = Class.forName("reflectdemo.Student");
            Method method = c.getDeclaredMethod("function", String.class);
            method.setAccessible(true);
            Student student = (Student) c.newInstance();
            //传参给function()
            method.invoke(student, "我是一个私有方法！！");
        } catch (ClassNotFoundException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有属性
    private static void reflectPrivateField() {
        try {
            Class<?> c = Class.forName("reflectdemo.Student");
            Field field = c.getDeclaredField("name");
            //修改私有属性name
            field.setAccessible(true);
            Student student = (Student)c.newInstance();
            field.set(student, "Ming");
            System.out.println(student);
        } catch (ClassNotFoundException | NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有的构造方法 屏蔽内容为获得公有的构造方法
    private static void reflectPrivateConstructor() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Constructor<Student> constructor =
                    (Constructor<Student>)c1.getDeclaredConstructor(String.class, int.class);
            constructor.setAccessible(true);//打一声招呼
            Student student = constructor.newInstance("张三", 19);
            System.out.println(student);
        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException |
                 InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }


    //创建对象
    private static void reflectNewInstance() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();
            System.out.println(student);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
